package com.ssy.lingxi.marketing.serviceimpl.component.activity;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.marketing.BelongTypeEnum;
import com.ssy.lingxi.common.constant.member.AbilitySuitableMemberEnum;
import com.ssy.lingxi.common.constant.member.PlatformSuitableMemberEnum;
import com.ssy.lingxi.common.model.bo.MemberAndRoleIdBO;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.marketing.entity.activity.*;
import com.ssy.lingxi.marketing.model.bo.ActivityGoodsBO;
import com.ssy.lingxi.marketing.model.constant.ActivityGoodsAuditStatusEnum;
import com.ssy.lingxi.marketing.model.constant.MerchantActivityInnerStatusEnum;
import com.ssy.lingxi.marketing.model.constant.PlatformActivityOuterStatusEnum;
import com.ssy.lingxi.marketing.repository.ActivityGoodsRepository;
import com.ssy.lingxi.marketing.repository.ActivityMemberLevelRepository;
import com.ssy.lingxi.marketing.repository.MerchantActivityRepository;
import com.ssy.lingxi.marketing.repository.PlatformActivityRepository;
import com.ssy.lingxi.marketing.serviceimpl.component.SuitableFieldComponent;
import com.ssy.lingxi.marketing.serviceimpl.component.SuitableMemberInfoComponent;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.AtSubMemberSuitableMemberVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.PfSubMemberSuitableMemberVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 活动商品计算服务实现类
 * @author yzc
 * @version 2.0.0
 * @date 2021/9/2
 */
@Slf4j
@Service
public class ActivityPriceCalculateComponent  {
    @Resource
    private JPAQueryFactory queryFactory;
    @Resource
    private ActivityGoodsRepository goodsRepository;
    @Resource
    private PlatformActivityRepository platformActivityRepository;
    @Resource
    private MerchantActivityRepository merchantActivityRepository;
    @Resource
    private SuitableMemberInfoComponent suitableMemberInfoComponent;
    @Resource
    private ActivityMemberLevelRepository activityMemberLevelRepository;
    @Resource
    private  ActivityCheckRuleComponent activityCheckRuleComponent;


    //查询sku参与平台的所有活动
    public List<ActivityGoodsBO> selectPlatformActivity(Long shopId, List<Long> productIds, Long skuId) {
        QActivityGoodsDO goodsDO = QActivityGoodsDO.activityGoodsDO;
        QPlatformActivityDO platformActivityDO = QPlatformActivityDO.platformActivityDO;
        QActivityShopDO activityShopDO = QActivityShopDO.activityShopDO;

        BooleanBuilder predicates = new BooleanBuilder();
        // 进行中
        predicates.and(platformActivityDO.outerStatus.eq(PlatformActivityOuterStatusEnum.ONGOING.getCode()));
        // 当前时间在活动时间内
        long currentTimeMillis = System.currentTimeMillis();
        predicates.and(platformActivityDO.startTime.loe(currentTimeMillis));
        predicates.and(platformActivityDO.endTime.goe(currentTimeMillis));

        predicates.and(goodsDO.belongType.eq(BelongTypeEnum.PLATFORM.getCode()));
        //审核通过的
        predicates.and(goodsDO.auditStatus.eq(ActivityGoodsAuditStatusEnum.AGREE.getCode()));
        predicates.and(activityShopDO.shopId.eq(shopId));
        if (!CollectionUtils.isEmpty(productIds)) {
            predicates.and(goodsDO.productId.in(productIds));
        }
        if (Objects.nonNull(skuId)) {
            predicates.and(goodsDO.skuId.eq(skuId));
        }

        JPAQuery<ActivityGoodsBO> queryJpaQuery = queryFactory.select(Projections.bean(ActivityGoodsBO.class,
                goodsDO.id,
                goodsDO.activityId,
                goodsDO.belongType,
                platformActivityDO.activityType,
                platformActivityDO.activityDefined,
                platformActivityDO.startTime,
                platformActivityDO.endTime,
                platformActivityDO.activityName,
                goodsDO.memberId,
                goodsDO.roleId,
                goodsDO.productId,
                goodsDO.skuId,
                goodsDO.price,
                goodsDO.plummetPrice,
                goodsDO.activityPrice,
                goodsDO.deductionPrice,
                goodsDO.discount,
                goodsDO.restrictNum,
                goodsDO.restrictTotalNum))
                .from(goodsDO)
                .leftJoin(platformActivityDO).on(platformActivityDO.id.eq(goodsDO.activityId))
                .leftJoin(activityShopDO).on(activityShopDO.activityId.eq(platformActivityDO.id).and(activityShopDO.belongType.eq(BelongTypeEnum.PLATFORM.getCode())));

        queryJpaQuery.where(predicates);

        return queryJpaQuery.orderBy(platformActivityDO.createTime.desc()).fetch();
    }

    //查询sku参与会员自建的所有活动
    public List<ActivityGoodsBO> selectMerchantActivity(Long shopId, List<Long> productIds, Long skuId) {
        QActivityGoodsDO goodsDO = QActivityGoodsDO.activityGoodsDO;
        QMerchantActivityDO merchantActivityDO = QMerchantActivityDO.merchantActivityDO;
        QActivityShopDO activityShopDO = QActivityShopDO.activityShopDO;

        BooleanBuilder predicates = new BooleanBuilder();
        // 进行中
        predicates.and(merchantActivityDO.innerStatus.eq(MerchantActivityInnerStatusEnum.ONGOING.getCode()));
        // 当前时间在活动时间内
        long currentTimeMillis = System.currentTimeMillis();
        predicates.and(merchantActivityDO.startTime.loe(currentTimeMillis));
        predicates.and(merchantActivityDO.endTime.goe(currentTimeMillis));

        predicates.and(goodsDO.belongType.eq(BelongTypeEnum.MERCHANT.getCode()));
        predicates.and(activityShopDO.shopId.eq(shopId));
        if (!CollectionUtils.isEmpty(productIds)) {
            predicates.and(goodsDO.productId.in(productIds));
        }
        if (Objects.nonNull(skuId)) {
            predicates.and(goodsDO.skuId.eq(skuId));
        }

        JPAQuery<ActivityGoodsBO> queryJpaQuery = queryFactory.select(Projections.bean(ActivityGoodsBO.class,
                goodsDO.id,
                goodsDO.activityId,
                goodsDO.belongType,
                merchantActivityDO.activityType,
                merchantActivityDO.activityDefined,
                merchantActivityDO.startTime,
                merchantActivityDO.endTime,
                merchantActivityDO.activityName,
                goodsDO.memberId,
                goodsDO.roleId,
                goodsDO.productId,
                goodsDO.skuId,
                goodsDO.price,
                goodsDO.plummetPrice,
                goodsDO.activityPrice,
                goodsDO.deductionPrice,
                goodsDO.discount,
                goodsDO.restrictNum,
                goodsDO.restrictTotalNum))
                .from(goodsDO)
                .leftJoin(merchantActivityDO).on(merchantActivityDO.id.eq(goodsDO.activityId))
                .leftJoin(activityShopDO).on(activityShopDO.activityId.eq(merchantActivityDO.id).and(activityShopDO.belongType.eq(BelongTypeEnum.MERCHANT.getCode())));

        queryJpaQuery.where(predicates);

        return queryJpaQuery.orderBy(merchantActivityDO.createTime.desc()).fetch();
    }

    //汇总排序活动
    private List<ActivityGoodsBO> activityGoodsMergeAndSort(List<ActivityGoodsBO> platformActivityGoodsList, List<ActivityGoodsBO> merchantActivityGoodsList) {
        platformActivityGoodsList.addAll(merchantActivityGoodsList);
        return platformActivityGoodsList.stream().sorted(Comparator.comparing(ActivityGoodsBO::getStartTime)).collect(Collectors.toList());
    }

    /**
     * 检查平台活动的会员等级规则
     * @param platformActivityDO 平台活动
     * @param subMemberSuitableMemberVO 适用会员等级信息
     * @return 匹配到的适用会员
     */
    public PlatformSuitableMemberEnum checkPlatformMemberLevelRule(PlatformActivityDO platformActivityDO, PfSubMemberSuitableMemberVO subMemberSuitableMemberVO) {
        PlatformSuitableMemberEnum suitableMemberEnum = null;
        // 适用会员
        List<Integer> suitableMemberList = SuitableFieldComponent.parseCouponSuitableMember(platformActivityDO.getSuitableMember());
        if (suitableMemberList.contains(PlatformSuitableMemberEnum.NEW_PLATFORM_MEMBER.getCode()) && subMemberSuitableMemberVO.isNewMember()) {
            suitableMemberEnum = PlatformSuitableMemberEnum.NEW_PLATFORM_MEMBER;
        } else if (suitableMemberList.contains(PlatformSuitableMemberEnum.OLD_PLATFORM_MEMBER.getCode()) && subMemberSuitableMemberVO.isOldMember()) {
            suitableMemberEnum = PlatformSuitableMemberEnum.OLD_PLATFORM_MEMBER;
        } else {
            return null;
        }

        // 会员类型
        List<Integer> MemberTypeList = SuitableFieldComponent.parseMarketingMemberType(platformActivityDO.getSuitableMemberType());
        if (!MemberTypeList.contains(subMemberSuitableMemberVO.getMemberType())) {
            return null;
        }

        // 适用会员等级
        List<ActivityMemberLevelDO> memberLevelDOList = activityMemberLevelRepository.findByBelongTypeAndActivityId(BelongTypeEnum.PLATFORM.getCode(), platformActivityDO.getId());
        if (!CollectionUtils.isEmpty(memberLevelDOList)) {
            if (!activityCheckRuleComponent.containsPlatformMemberLevel(memberLevelDOList, subMemberSuitableMemberVO)) {
                return null;
            }
        }

        return suitableMemberEnum;
    }

    public Wrapper<List<ActivityGoodsBO>> checkPlatformActivity(MemberAndRoleIdBO memberAndRoleIdBO, List<ActivityGoodsBO> platformActivityDOList) {
        List<ActivityGoodsBO> resultList = new ArrayList<>();

        if (CollectionUtils.isEmpty(platformActivityDOList)) {
            return Wrapper.success(resultList);
        }

        Map<Long, List<ActivityGoodsBO>> activityMap = platformActivityDOList.stream().collect(Collectors.groupingBy(ActivityGoodsBO::getActivityId));

        PfSubMemberSuitableMemberVO subMemberSuitableMemberVO = null;
        if (Objects.nonNull(memberAndRoleIdBO)) {
            // 查询会员关系
            subMemberSuitableMemberVO = suitableMemberInfoComponent.getPlatformSubMemberSuitableMember(memberAndRoleIdBO.getMemberId(), memberAndRoleIdBO.getRoleId());
            if (Objects.isNull(subMemberSuitableMemberVO)) {
                return Wrapper.success();
            }
        }


        for (Map.Entry<Long, List<ActivityGoodsBO>> entry : activityMap.entrySet()) {
            List<ActivityGoodsBO> activityGoodsBOList = entry.getValue();
            if (CollectionUtils.isEmpty(activityGoodsBOList)) {
                continue;
            }
            ActivityGoodsBO activityGoodsBO = activityGoodsBOList.get(0);
            if (Objects.nonNull(memberAndRoleIdBO)) {
                // TODO 代码优化
                PlatformActivityDO platformActivityDO = platformActivityRepository.findById(activityGoodsBO.getActivityId()).orElse(null);
                PlatformSuitableMemberEnum suitableMemberEnum = checkPlatformMemberLevelRule(platformActivityDO, subMemberSuitableMemberVO);
                if (Objects.isNull(suitableMemberEnum)) {
                    continue;
                }
            }

            resultList.addAll(activityGoodsBOList);
        }

        return Wrapper.success(resultList);
    }

    /**
     * 检查商家活动的会员等级规则
     * [如果用户成为商户会员，那么用户不再属于新用户或者老用户，当商户创建活动，只勾选1,2项时，该会员不能参加此活动]
     * @param memberId 当前登录的会员id
     * @param roleId 当前登录的会员角色id
     * @param merchantActivityDO 商家活动
     * @param subMemberSuitableMemberVOList 适用会员等级信息
     * @return 匹配到的适用会员
     */
    public AbilitySuitableMemberEnum checkMerchantMemberLevelRule(Long memberId, Long roleId, MerchantActivityDO merchantActivityDO, List<AtSubMemberSuitableMemberVO> subMemberSuitableMemberVOList) {
        // 查找会员关系
        AtSubMemberSuitableMemberVO subMemberSuitableMemberVO = subMemberSuitableMemberVOList.stream()
                .filter(e -> merchantActivityDO.getMemberId().equals(e.getUpperMemberId())
                        && merchantActivityDO.getRoleId().equals(e.getUpperRoleId())
                        && memberId.equals(e.getMemberId())
                        && roleId.equals(e.getRoleId())
                )
                .findFirst()
                .orElse(null);
        if (Objects.isNull(subMemberSuitableMemberVO)) {
            return null;
        }

        AbilitySuitableMemberEnum suitableMemberEnum = null;
        // 适用会员
        List<Integer> suitableUserList = SuitableFieldComponent.parseCouponSuitableUser(merchantActivityDO.getSuitableUser());
        // 是否为下级会员
        if (subMemberSuitableMemberVO.isSubMemberRelation()) {
            if (suitableUserList.contains(AbilitySuitableMemberEnum.NEW_MEMBER.getCode()) && subMemberSuitableMemberVO.isNewMember()) {
                // 新用户
                suitableMemberEnum = AbilitySuitableMemberEnum.NEW_MEMBER;
            } else if (suitableUserList.contains(AbilitySuitableMemberEnum.OLD_MEMBER.getCode()) && subMemberSuitableMemberVO.isOldMember()) {
                // 老用户
                suitableMemberEnum = AbilitySuitableMemberEnum.OLD_MEMBER;
            } else {
                return null;
            }

            // 判断适用会员等级
            List<ActivityMemberLevelDO> memberLevelDOList = activityMemberLevelRepository.findByBelongTypeAndActivityId(BelongTypeEnum.MERCHANT.getCode(), merchantActivityDO.getId());
            if (!CollectionUtils.isEmpty(memberLevelDOList)) {
                if (!activityCheckRuleComponent.containsAbilityMemberLevel(memberLevelDOList, subMemberSuitableMemberVO)) {
                    return null;
                }
            }

        } else {
            if (suitableUserList.contains(AbilitySuitableMemberEnum.NEW_USER.getCode()) && subMemberSuitableMemberVO.isNewUser()) {
                // 新用户
                suitableMemberEnum = AbilitySuitableMemberEnum.NEW_USER;
            } else if (suitableUserList.contains(AbilitySuitableMemberEnum.OLD_USER.getCode()) && subMemberSuitableMemberVO.isOldUser()) {
                // 老用户
                suitableMemberEnum = AbilitySuitableMemberEnum.OLD_USER;
            } else {
                return null;
            }
        }

        return suitableMemberEnum;
    }

    public Wrapper<List<ActivityGoodsBO>> checkMerchantActivity(MemberAndRoleIdBO memberAndRoleIdBO, List<ActivityGoodsBO> merchantActivityDOList) {
        List<ActivityGoodsBO> resultList = new ArrayList<>();

        if (CollectionUtils.isEmpty(merchantActivityDOList)) {
            return Wrapper.success(resultList);
        }

        List<AtSubMemberSuitableMemberVO> subMemberSuitableMemberVOList = null;
        if (Objects.nonNull(memberAndRoleIdBO)) {
            // 查询会员关系
            subMemberSuitableMemberVOList = suitableMemberInfoComponent.listAbilitySubMemberSuitableMember(memberAndRoleIdBO.getMemberId(), memberAndRoleIdBO.getRoleId(),
                    merchantActivityDOList.stream().map(e -> new MemberAndRoleIdBO(e.getMemberId(), e.getRoleId())).collect(Collectors.toList()));
            if (CollectionUtils.isEmpty(subMemberSuitableMemberVOList)) {
                return Wrapper.success(Collections.emptyList());
            }
        }

        Map<Long, List<ActivityGoodsBO>> activityMap = merchantActivityDOList.stream().collect(Collectors.groupingBy(ActivityGoodsBO::getActivityId));

        for (Map.Entry<Long, List<ActivityGoodsBO>> entry : activityMap.entrySet()) {
            List<ActivityGoodsBO> activityGoodsBOList = entry.getValue();
            if (CollectionUtils.isEmpty(activityGoodsBOList)) {
                continue;
            }
            ActivityGoodsBO activityGoodsBO = activityGoodsBOList.get(0);
            if (Objects.nonNull(memberAndRoleIdBO)) {
                // TODO 代码优化
                MerchantActivityDO merchantActivityDO = merchantActivityRepository.findById(activityGoodsBO.getActivityId()).orElse(null);
                AbilitySuitableMemberEnum suitableMemberEnum = checkMerchantMemberLevelRule(memberAndRoleIdBO.getMemberId(), memberAndRoleIdBO.getRoleId(), merchantActivityDO, subMemberSuitableMemberVOList);
                if (Objects.isNull(suitableMemberEnum)) {
                    continue;
                }
            }

            resultList.addAll(activityGoodsBOList);
        }

        return Wrapper.success(resultList);
    }


    public List<ActivityGoodsBO> getSkuAllActivityList(Long shopId, Long skuId, MemberAndRoleIdBO memberAndRoleIdBO){
        // 平台活动商品
        List<ActivityGoodsBO> platformActivityGoodsList = selectPlatformActivity(shopId, null, skuId);
        List<ActivityGoodsBO> platformActivityDOList = checkPlatformActivity(memberAndRoleIdBO, platformActivityGoodsList).getData();
        // 商家活动商品
        List<ActivityGoodsBO> merchantActivityGoodsList = selectMerchantActivity(shopId, null, skuId);
        List<ActivityGoodsBO> merchantActivityDOList = checkMerchantActivity(memberAndRoleIdBO, merchantActivityGoodsList).getData();
        // 汇总活动商品
        return activityGoodsMergeAndSort(platformActivityDOList, merchantActivityDOList);
    }


}
